home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 014 / libtools.arc / SPOOLER.AQM / SPOOLER.ASM
Encoding:
Assembly Source File  |  1984-04-08  |  8.5 KB  |  294 lines

  1.     PAGE    60,128
  2.     TITLE    Asynchronous Print Program - SPOOLER.ASM V1.0
  3.     PAGE
  4.     COMMENT    *
  5.     
  6.     PROGRAM:    SPOOLER.ASM  Version 1.0
  7.     AUTHOR:        Valdis Skuja
  8.     DATE:        September 15,1982
  9.  
  10.  
  11.             MODULE DESCRIPTION
  12.             ------------------
  13.  
  14.              This program sets up an environment in which 
  15.         any output for the printer is buffered before being
  16.         printed. After the output is placed into the buffer
  17.         control is passed back to the caller. The output is
  18.         then printed asynchronously. The asynchronous print
  19.         routine is given control at each tick of the system
  20.         timer, at which time it keeps sending the buffered
  21.         print output to the printer until the printer is
  22.         busy.
  23.              Using this method the program printing does 
  24.         not have to wait for the printed output to complete
  25.         before continuing, therefore making better use of 
  26.         the CPU and allows the user to run other programs as
  27.         the printer is still printing.
  28.              The buffer size is set in the program as 16K, but
  29.         this can be changed by changing the values in the 
  30.         define statements for "BUFSIZE" and "BUFFER_AREA" and
  31.         then reassembling and relinking the program.
  32.              To invoke this program it must be assembled and
  33.         linked as SPOOLER.EXE then while in DOS issue the
  34.         command SPOOLER. When invoked the program will remain
  35.         resident and can only be removed by re-booting DOS.
  36.         Do not invoke the program more than once without 
  37.         re-booting as it will grab an additional 16K of your
  38.         RAM each time it is called.
  39.              Anyone having any questions or problems about
  40.         using this program can contact me at 223-2528, and
  41.         I will try to help you if I can.
  42.  
  43.                         Valdis Skuja.
  44.  
  45.         *
  46. BIOS_DATA    SEGMENT    AT 40H
  47.         ORG    8H
  48. PRINTER_BASE    DW    4 DUP(?)
  49.         ORG    3FH
  50. MOTOR_STATUS    DB    ?
  51. MOTOR_COUNT    DB    ?
  52.         ORG    6CH
  53. TIMER_LOW    DW    ?
  54. TIMER_HIGH    DW    ?
  55. TIMER_OFL    DB     ?
  56. BIOS_DATA    ENDS
  57. STACK        SEGMENT    PARA STACK 'STACK'
  58.         DB    10 DUP('STACK   ')
  59. STACK        ENDS
  60. CSEG        SEGMENT    PARA PUBLIC 'CODE'
  61.         ASSUME    CS:CSEG,DS:BIOS_DATA,ES:CSEG,SS:STACK
  62. INIT_ROUTINE    PROC    FAR
  63.         JMP    START            ;BR. AROUND BUFFER
  64. FLAGS        DB    0            ;FLAGS BYTE
  65. BF_FULL        EQU    80H            ;BUFFER FULL
  66. BF_EMPTY    EQU    40H            ;BUFFER EMPTY
  67. IO_ACTIVE    EQU    20H            ;IO CURRENTLY ACTIVE
  68. SOFTWARE_INT    EQU    10H            ;SOFTWARE INTERRUPT
  69. NOT_FULL    EQU    7FH            ;BUFFER NOT FULL
  70. NOT_EMPTY    EQU    0BFH            ;BUFFER NOT EMPTY
  71. IO_NOT_ACTIVE    EQU    0DFH            ;NO IO ACTIVE
  72. NOT_SOFTWARE    EQU    0EFH            ;NOT SOFTWARE INT.
  73. ;
  74. INTA00        EQU    20H
  75. INTA01        EQU    21H
  76. EOI        EQU    20H            ;END OF INTERUPT
  77. ;
  78. BUFSIZE        DW    16384            ;BUFFER SIZE
  79. PRINTER_@    DW    0            ;PRINTER ADDRESS
  80. FIRST_CHAR    DW    0            ;FIRST CHAR. POINTER
  81. LAST_CHAR    DW    0            ;LAST CHAR. POINTER
  82. BUFFER_AREA    DB    16384 DUP(?)        ;BUFFER AREA 24K
  83. END_OF_BUF    EQU    $            ;END OF BUFFER
  84. START:
  85.         PUSH    AX            ;SAVE AX CONTENTS
  86.         PUSH    DS            ;SAVE DS CONTENTS
  87.         OR    FLAGS,BF_EMPTY        ;SET BUFFER EMPTY
  88.         MOV    DX,OFFSET PRINTER_INT    ;GET PRINTER INT. RTN.
  89.         MOV    AX,CS            ;GET SEG PTR.
  90.         MOV    DS,AX            ;SET INT "40" CSEG
  91.         MOV    AH,25H            ;DOS CALL - SET INT.
  92.         MOV    AL,40H            ;INDICATE INT. "40"
  93.         INT    21H            ;CALL DOS
  94.         MOV    DX,OFFSET PRINT_IO    ;GET PRINT IO RTN.
  95.         MOV    AX,CS            ;GET SEG PTR.
  96.         MOV    DS,AX            ;SET INT "17" CSEG
  97.         MOV    AH,25H            ;DOS CALL - SET INT.
  98.         MOV    AL,17H            ;REPLACE INT "17"
  99.         INT    21H            ;CALL DOS
  100.         MOV    DX,OFFSET TIMER_INT    ;GET TIMER_INT TRN
  101.         MOV    AX,CS            ;GET SEG PTR.
  102.         MOV    DS,AX            ;SET INT "8" CSEG
  103.         MOV    AH,25H            ;DOS CALL - SET INT.
  104.         MOV    AL,08H            ;REPLACE INT "8"
  105.         INT    21H            ;CALL DOS
  106.         PUSH    DS            ;SAVE DS
  107.         PUSH    DX            ;SAVE DX
  108.         MOV    DX,BIOS_DATA        
  109.         MOV    DS,DX
  110.         MOV    DX,PRINTER_BASE        ;@ OF 1ST PRINTER
  111.         MOV    PRINTER_@,DX        ;SAVE PRINTER @
  112.         ADD    DX,2            ;POINT TO OUTPUT PORT
  113.         MOV    AL,8            ;SET INIT LINE LOW
  114.         OUT    DX,AL    
  115.         MOV    AX,1000
  116. INIT_LOOP:
  117.         DEC    AX            ;LOOP FOR RESET TO TAKE
  118.         JNZ    INIT_LOOP        ;INIT_LOOP
  119.         MOV    AL,0CH            ;INT. OFF TO START
  120.         OUT    DX,AL
  121.         MOV    DX,OFFSET BUFFER_AREA    ;LOCATE BUFFER AREA
  122.         MOV    FIRST_CHAR,DX        ;AND SET UP THE FIRST
  123.         MOV    LAST_CHAR,DX        ;AND LAST CHAR POINTERS
  124.         POP    DX            ;RESTORE DX
  125.         POP    DS            ;RESTORE DS
  126.         PUSH    ES            ;PUSH PGM PREFIX @
  127.         MOV    AX,CS            ;CURRENT CSEG 
  128.         PUSH    CX            ;SAVE CX
  129.         MOV    CX,ES            ;@ OF PGM PREFIX
  130.         SUB    AX,CX            ;OFFSET FROM PGM. PRFX.
  131.         MOV    CL,4
  132.         SHL    AX,CL            ;MULT. BY 16
  133.         MOV    DX,AX            ;SAVE FOR LATER
  134.         POP    CX            ;RESTORE CX
  135.         ADD    AX,OFFSET NEXT_INSTR    ;CALC NEXT INSTR OFFSET
  136.         PUSH    AX            ;SAVE NEXT INST OFFSET
  137.         RET                ;GOTO NEXT INSTR.76
  138. NEXT_INSTR:
  139.         POP    DS            ;RESTORE DS
  140.         POP    AX            ;RESTORE AX
  141.         ADD    DX,OFFSET PGM_END    ;LOCATE END OF PGM.
  142.         INT    27H            ;END BUT STAY RESIDENT
  143. INIT_ROUTINE    ENDP
  144. ;
  145. ;
  146. PRINTER_INT    PROC    NEAR
  147.         ASSUME    CS:CSEG,DS:CSEG,ES:CSEG,SS:STACK
  148.         PUSH    SI            ;SAVE SI
  149.         PUSH    DS            ;SAVE DS
  150.         PUSH    ES            ;SAVE ES
  151.         PUSH    AX            ;SAVE AX
  152.         PUSH    BX            ;SAVE BX
  153.         PUSH    CX            ;SAVE CX
  154.         PUSH    DX            ;SAVE DX
  155.         MOV    SI,CSEG            
  156.         MOV    DS,SI            ;SET UP DS
  157.         MOV    ES,SI            ;SET UP ES
  158. NEXT_CHAR:
  159.         TEST    FLAGS,BF_EMPTY        ;BUFFER EMPTY?
  160.         JZ    CHECK_FOR_EMPTY        ;B.I.N
  161.         JMP    PRINTER_INT_RET        ;RETURN FROM INTERRUPT
  162. CHECK_FOR_EMPTY:
  163.         MOV    SI,FIRST_CHAR        ;OFFSET TO PRINT CHAR
  164.         CMP    SI,LAST_CHAR        ;IS THIS LAST CHAR.
  165.         JNE    NOT_LAST_CHAR        ;B.I.N
  166.         OR    FLAGS,BF_EMPTY        ;SET BUFFER EMPTY
  167. NOT_LAST_CHAR:
  168.         CLD                ;CLEAR DIRECTION FLAG
  169. ;                         TO INCREMENT SI
  170.         LODSB                ;GET CHAR IN AL
  171.         CMP    SI,OFFSET END_OF_BUF    ;END OF BUFFER?
  172.         JNE    PRINT_THE_CHAR        ;NO, BRANCH
  173.         MOV    SI,OFFSET BUFFER_AREA    ;BEGINNING OF BUFFER
  174. PRINT_THE_CHAR:
  175.         MOV    DX,PRINTER_@        ;GET PRINTER ADDR.
  176.         MOV    CX,100            ;SET BUSY LOOP COUNTER
  177.         OUT    DX,AL            ;PRINT THE CHAR.
  178.         INC    DX            ;POINT TO STATUS PORT
  179. WAIT_NOT_BUSY:
  180.         IN    AL,DX            ;GET PRINTER STATUS
  181.         TEST    AL,80H            ;STILL BUSY?
  182.         JNZ    OUT_STROBE        ;OUT STROBE
  183.         LOOP     WAIT_NOT_BUSY        ;KEEP TRYING
  184.         AND    FLAGS,NOT_EMPTY        ;STILL BUSY-SET NOT EMPTY
  185.         JMP    PRINTER_INT_RET        ;AND RETURN W/O PRINTING
  186. OUT_STROBE:
  187.         MOV    AL,1DH            ;STROBE HIGH
  188.         INC    DX            ;POINT TO OUTPUT PORT
  189.         OUT    DX,AL            
  190.         MOV    AL,1CH            ;STROBE LOW
  191.         OUT    DX,AL
  192.         MOV    FIRST_CHAR,SI        ;SET NEXT CHAR TO PRINT
  193.         AND    FLAGS,NOT_FULL        ;SET BUFFER NOT FULL
  194.         JMP    NEXT_CHAR        ;PRINT NEXT CHAR
  195. PRINTER_INT_RET:
  196.         POP    DX            ;RESTORE DX
  197.         POP    CX            ;RESTORE CX
  198.         POP    BX            ;RESTORE BX
  199.         POP    AX            ;RESTORE AX
  200.         POP    ES            ;RESTORE ES
  201.         POP    DS            ;RESTORE DS
  202.         POP    SI            ;RESTORE SI
  203.         IRET
  204. PRINTER_INT    ENDP
  205. ;
  206. ;
  207. PRINT_IO    PROC    NEAR
  208.         ASSUME    CS:CSEG,DS:CSEG,ES:CSEG,SS:STACK
  209.         PUSH    DI            ;SAVE DI
  210.         PUSH    DS            ;SAVE DS
  211.         PUSH    ES            ;SAVE ES
  212.         PUSH    BX            ;SAVE BX
  213.         MOV    DI,CSEG            
  214.         MOV    ES,DI            ;SET UP ES
  215.         MOV    DS,DI            ;SET UP DS
  216.         OR    AH,AH            ;PRINT FUNCTION?
  217.         JNZ    PRINT_IO_RET        ;NO, RETURN
  218.         TEST    FLAGS,BF_EMPTY        ;BUFFER EMPTY?
  219.         JZ    SAVE_NEXT_CHAR        ;B.I.N
  220.         MOV    DI,FIRST_CHAR        ;GET PTR. TO 1ST CHAR
  221.         MOV    LAST_CHAR,DI        ;LAST CHAR = 1ST CHAR
  222.         STOSB                ;MOVE CHAR TO BUFFER
  223.         AND    FLAGS,NOT_EMPTY        ;IND. BUFFER NOT EMPTY
  224.         JMP    PRINT_IO_RET        ;RETURN TO CALLER
  225. SAVE_NEXT_CHAR:
  226.         MOV    BX,LAST_CHAR        ;GET LAST CHAR. PTR.
  227.         INC    BX            ;POINT TO NEXT CHAR.
  228.         CMP    BX,OFFSET END_OF_BUF    ;END OF BUFFER?
  229.         JNE    CHECK_FOR_FULL        ;B.I.N
  230.         MOV    BX,OFFSET BUFFER_AREA    ;BEGINNING OF BUFFER
  231. CHECK_FOR_FULL:
  232.         CMP    BX,FIRST_CHAR        ;LAST_CHAR = FIRST_CHAR
  233.         JNE    SAVE_CHAR        ;B.I.N
  234.         OR    FLAGS,BF_FULL         ;SET BUFFER FULL
  235.         STI                ;START INTERRUPTS
  236. FULL_LOOP:
  237.         TEST    FLAGS,BF_FULL        ;FULL BUFFER?
  238.         JNZ    FULL_LOOP        ;LOOP IF FULL
  239.         CLI                ;STOP INTERRUPTS
  240.         JMP    SAVE_NEXT_CHAR        ;TRY AGAIN
  241. SAVE_CHAR:
  242.         MOV    LAST_CHAR,BX        ;UPDATE LAST_CHAR
  243.         MOV    DI,BX
  244.         STOSB
  245.         AND    FLAGS,NOT_EMPTY        ;IND. BUFFER NOT EMPTY
  246. PRINT_IO_RET:
  247.         POP    BX            ;RESTORE BX
  248.         POP    ES            ;RESTORE ES
  249.         POP    DS            ;RESTORE DS
  250.         POP    DI            ;RESTORE DI
  251.         SUB    AH,AH            ;CLEAR RETURN CODE
  252.         IRET                
  253. PRINT_IO    ENDP
  254. TIMER_INT    PROC    NEAR
  255.     ASSUME    CS:CSEG,DS:BIOS_DATA
  256.     STI            ;INTERRUPTS BACK ON
  257.     PUSH    DS
  258.     PUSH    AX
  259.     PUSH    DX        ;SAVE MACHINE STATE
  260.     MOV    AX,BIOS_DATA
  261.     MOV    DS,AX        ;ESTABLISH ADDRESSABILITY
  262.     INC    TIMER_LOW    ;INCREMENT TIME
  263.     JNZ    T4        ;TEST_DAY
  264.     INC    TIMER_HIGH    ;INCREMENT HIGH WORD OF TIME
  265. T4:                ;TEST_DAY
  266.     CMP    TIMER_HIGH,018H    ;TEST FOR COUNT EQUALLING 24 HOURS
  267.     JNZ    T5        ;DISKETTE_CTL
  268.     CMP    TIMER_LOW,0B0H
  269.     JNZ    T5        ;DISKETTE_CTL
  270. ;------    TIMER HAS GONE 24 HOURS
  271.     MOV    TIMER_HIGH,0
  272.     MOV    TIMER_LOW,0
  273.     MOV    TIMER_OFL,1
  274. T5:                ;DISKETTE_CTL
  275.     DEC    MOTOR_COUNT
  276.     JNZ    T6        ;RETURN IF COUNT NOT OUT
  277.     AND    MOTOR_STATUS,0F0H    ;TURN OFF MOTOR RUNNING BITS
  278.     MOV    AL,0CH
  279.     MOV    DX,03F2H        ;FDC CTL PORT
  280.     OUT    DX,AL        ;TURN OFF THE MOTOR
  281. T6:                ;TIMER_RET
  282.     INT    1CH        ;TRANSFER CONTROL TO USER ROUTINE
  283.     INT    40H        ;TRANSFER CNTL TO ASYNC. PRINTER RTN.
  284.     MOV    AL,EOI
  285.     OUT    020H,AL        ;END OF INTERRUPT TO 8259
  286.     POP    DX
  287.     POP    AX
  288.     POP    DS        ;RESET MACHINE STATE
  289.     IRET            ;RETURN FROM INTERRUPT
  290. TIMER_INT    ENDP
  291. PGM_END:    DB    0
  292. CSEG        ENDS                ;END OF CODE SEG.
  293.         END    INIT_ROUTINE
  294.